<?php
/*
 * Copyright (c) 2013 Eugene Kuzmenko
 *
 * Permission  is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in  the Software without restriction, including without limitation the rights
 * to  use,  copy,  modify,  merge, publish, distribute, sublicense, and/or sell
 * copies  of  the  Software,  and  to  permit  persons  to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The  above  copyright  notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE  SOFTWARE  IS  PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED,  INCLUDING  BUT  NOT  LIMITED  TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS  FOR  A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS  OR  COPYRIGHT  HOLDERS  BE  LIABLE  FOR  ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * For more information, see <http://www.aljey.com>.
 */

namespace Al\HTTP\Lib\Vars;

use Al\Core\Lib\ParameterHolder,
    Al\HTTP\Lib\Route,
    Al\Core\Lib\Service;

/**
 * Hosts request-specific parameters.
 * 
 * @author Eugene Kuzmenko <mail@aljey.com>
 */
class Params extends ParameterHolder {

  /**
   * @var null|array Original data
   */
  protected $original = null;

  /**
   * @var bool True if this is a sub-request.
   */
  public $subrequest = false;
  
  /** {@inheritDoc} */
  public function __construct() {
    $service = Service::get();
    $found = false;
    parent::__construct(array(
      'path' => urldecode($service['http']['server']['uri'])));
    $config = $service['config'];
    if (is_array($routes = $config['routes'])) {
      foreach ($routes as $name => &$route) {
        $route = new Route($name, $route);
        if (!$found && false !== ($result = $route->match($this['path']))) {
          foreach ($result as $key => $value) $this[$key] = $value;
          $this['route'] = $route;
          $found = true;
        }
      }
      unset($route);
      $config['routes'] = $routes;
    }
    Service::get('http')->when('params',
      function (Params $params) use (&$service) {
        if (!$params['route']) $service['event']->fire('404');
      });
  }

  /**
   * Sets the new data
   *
   * @param Route $route
   * @param array $data
   */
  public function setData(Route $route, $data = array()) {
    if (is_null($this->original)) $this->original = $this->data;
    $this->data = array();
    foreach ($data as $key => $value) $this[$key] = $value;
    $this['route'] = $route;
    $this->subrequest = true;
    $this->rewind();
  }

  /**
   * Restores the original data
   */
  public function restoreData() {
    if (!is_null($this->original)) {
      $this->data = $this->original;
      $this->original = null;
      $this->subrequest = false;
      $this->rewind();
    }
  }

  /**
   * If this is a sub request returns the master request parameters.
   *
   * @return Params|array
   */
  public function getMaster() {
    return is_null($this->original) ? $this : $this->original;
  }
  
}